﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace FlexiPay
{
    public class MatrixTable
    {
        #region member variables - private
        //getters
        private int SlabId = 0;
        private int rowCount = 0;
        private int colCount = 0;

        //internal
        private string ROperator = "";
        private string COperator = "";

        //storage
        private DataTable flatDt;
        #endregion

        #region getters
        //for 1d, there is one extra row
        public int getRowCount() {
            if (colCount <= 1) return rowCount + 1;
            else return rowCount; 
        }
        public int getColumnCount() { return colCount; }
        public int getSlabId() { return SlabId; }
        public DataTable getFlatMatrix() { return flatDt; }
        public string getCOper() { return COperator; }
        public string getROper() { return ROperator; }
        #endregion

        #region constuctor - new matrix
        public MatrixTable(int si, int rows, string rop, int columns = 1, string cop = "")
        {
            //set dimensions 
            SlabId = si;
            rowCount = rows;
            colCount = columns;
            ROperator = rop;
            COperator = cop;

            createFlat();
        }

        private void createFlat()
        {
            flatDt = new DataTable();

            //create columns
            flatDt.Columns.Add("SlabId");
            flatDt.Columns.Add("RowNo");
            flatDt.Columns.Add("ColumnNo");
            flatDt.Columns.Add("Value");

            //populate datatable with default values
            for (int i = 0; i <= getRowCount() ; i++)
            {
                for (int j = 0; j <= colCount; j++)
                {
                    DataRow dr = flatDt.NewRow();
                    dr["SlabID"] = SlabId;
                    dr["RowNo"] = i;
                    dr["ColumnNo"] = j;
                    dr["Value"] = 0;
                    flatDt.Rows.Add(dr);
                }
            }
            flatDt.AcceptChanges();

            //save it in db
            updateMatrix2DB(flatDt);
        }
        #endregion

        #region constructor - existing matrix
        public MatrixTable(int si)
        {
            SlabId = si;
            RetrieveDimension();
            RetrieveDBValues();
        }

        private void RetrieveDimension()
        {
            string rowCmd = "Select Max(RowNo) from SlabValues where SlabId = '" + SlabId.ToString() + "'";
            string colCmd = "Select Max(ColumnNo) from SlabValues where SlabId = '" + SlabId.ToString() + "'";
            string ropCmd = "Select ROperator from Slabs where SlabId = '" + SlabId.ToString() + "'";
            string copCmd = "Select COperator from Slabs where SlabId = '" + SlabId.ToString() + "'";

            string rows = DataBaseMethods.ExecuteScalar(rowCmd);
            string cols = DataBaseMethods.ExecuteScalar(colCmd);
            string rop = DataBaseMethods.ExecuteScalar(ropCmd);
            string cop = DataBaseMethods.ExecuteScalar(copCmd);

            try
            {
                //get dimension
                rowCount = Convert.ToInt32(rows);
                colCount = Convert.ToInt32(cols);
                //get operators
                ROperator = rop;
                COperator = cop;
            }
            catch (Exception)
            {
                throw new Exception("Slab does not exist.");
            }

            if ((rowCount < 1) || (colCount < 1))
                throw new Exception("Invalid Slab Dimensions");

            return;
        }

        private void RetrieveDBValues()
        {
            //select command
            string selectCmd = "Select SlabId, RowNo, ColumnNo, Value from SlabValues where SlabId = '" + SlabId.ToString() + "' Order By RowNo, ColumnNo ";

            //get slab values - flat structure
            flatDt = DataBaseMethods.ExecuteSelectQuery(selectCmd);
        }
        #endregion

        #region update operations
        public void updateMatrix2DB(DataTable dtb)
        {
            //delete old values first and then add these
            string deleteCommand2 = "DELETE FROM SlabValues WHERE SlabId = '" + SlabId.ToString() + "'";
            DataBaseMethods.ExecuteNonQuery(deleteCommand2);

            DataBaseMethods.uploadDT2DB(dtb, "SlabValues");
            flatDt = dtb;
        }
        #endregion
    }
}